#pragma once

//C Head
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

//System Head
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

const char* path = "/home/ARMCSKGT/C语言文件夹/pipe进程通信/共享内存作业/.";
const int proj = 0666;
const int gsize = 4096;

//获取key
key_t getkey()
{
    key_t k = ftok(path,proj);
    if(k == -1)
    {
        printf("ftok get key error! %d:%s\n",errno,strerror(errno));
        exit(EOF);
    }
    return k;
}

//创建共享内存shm
static int FetchShm(key_t key, size_t size, int shmflg)
{
    int shmid = shmget(key,size,shmflg);
    if(shmid == -1)
    {
        printf("shmget error! %d:%s\n",errno,strerror(errno));
        exit(EOF);
    }
    return shmid;
}

int CreatShm()
{
    return FetchShm(getkey(), gsize, IPC_CREAT | IPC_EXCL | 0666); //创建共享内存权限为0666且必须为最新
}

int GetShm()
{
    return FetchShm(getkey(), gsize, IPC_CREAT); //创建共享内存，如果存在则返回这个共享内存的shmid
}

//连接共享内存
void* AttackShm(int shmid)
{
    void* shm = shmat(shmid,NULL,0);
    if((void*)shm == (void*)-1)
    {
        printf("shmat error! %d:%s\n",errno,strerror(errno));
        exit(EOF);
    }
    return shm;
}

//卸载共享内存 - 去链接
void UnLinkShm(void *shm)
{
    int n = shmdt(shm);
    if(n == -1)
    {
        printf("shmdt error! %d:%s\n",errno,strerror(errno));
        exit(EOF);
    }
}

//删除共享内存
void DelShm(int shmid)
{
    int n = shmctl(shmid,IPC_RMID,NULL);
        if(n == -1)
    {
        printf("shmctl delete error! %d:%s\n",errno,strerror(errno));
        exit(EOF);
    }
}